﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SceneLib
{
    public class Matrix
    {
        public float[,] M {get; set;}
        
        public Matrix()
        {
          M = new float[4 , 4];
          for(int i=0; i<4; i++)
          {
            for(int j=0; j<4; j++)
            {  
              if(i == j )
                M[i, j] = 1;
              else
                M[i, j] = 0;
            }
          }
        }

        public static Vector operator *(Matrix M, Vector v)
        {
            float x = M.M[0, 0] * v.x + M.M[0, 1] * v.y + M.M[0, 2] * v.z + M.M[0, 3] * v.w;
            float y = M.M[1, 0] * v.x + M.M[1, 1] * v.y + M.M[1, 2] * v.z + M.M[1, 3] * v.w;
            float z = M.M[2, 0] * v.x + M.M[2, 1] * v.y + M.M[2, 2] * v.z + M.M[2, 3] * v.w;
            float w = M.M[3, 0] * v.x + M.M[3, 1] * v.y + M.M[3, 2] * v.z + M.M[3, 3] * v.w;

            Vector transformedVector = new Vector(x, y, z, w);
            return transformedVector;
        }

        public static Matrix operator *(float scalar, Matrix M)
        {
            Matrix result = new Matrix();
            for (int i = 0; i < 4; i++)
            {
                for (int j = 0; j < 4; j++)
                {
                    result.M[i,j] = M.M[i,j] * scalar;
                }
            }

            return result;
        }

        public static Matrix operator *(Matrix M1, Matrix M2)
        {
            Vector v1 = new Vector(M2.M[0,0], M2.M[1,0], M2.M[2,0], M2.M[3,0]);
            Vector v2 = new Vector(M2.M[0,1], M2.M[1,1], M2.M[2,1], M2.M[3,1]);
            Vector v3 = new Vector(M2.M[0,2], M2.M[1,2], M2.M[2,2], M2.M[3,2]);
            Vector v4 = new Vector(M2.M[0,3], M2.M[1,3], M2.M[2,3], M2.M[3,3]);

            Vector v1Result = M1 * v1;
            Vector v2Result = M1 * v2;
            Vector v3Result = M1 * v3;
            Vector v4Result = M1 * v4;

            Matrix result = new Matrix();
            result.M[0,0] = v1Result.x;
            result.M[0, 1] = v2Result.x;
            result.M[0, 2] = v3Result.x;
            result.M[0, 3] = v4Result.x;
            result.M[1, 0] = v1Result.y;
            result.M[1, 1] = v2Result.y;
            result.M[1, 2] = v3Result.y;
            result.M[1, 3] = v4Result.y;
            result.M[2, 0] = v1Result.z;
            result.M[2, 1] = v2Result.z;
            result.M[2, 2] = v3Result.z;
            result.M[2, 3] = v4Result.z;
            result.M[3, 0] = v1Result.w;
            result.M[3, 1] = v2Result.w;
            result.M[3, 2] = v3Result.w;
            result.M[3, 3] = v4Result.w;
            return result;
        }

        public static Matrix GetRotationMatrix(Vector x, Vector y, Vector z)
        {
            Matrix mRot = new Matrix();
            mRot.M[0, 0] = x.x;
            mRot.M[1, 0] = x.y;
            mRot.M[2, 0] = x.z;
            mRot.M[0, 1] = y.x;
            mRot.M[1, 1] = y.y;
            mRot.M[2, 1] = y.z;
            mRot.M[0, 2] = z.x;
            mRot.M[1, 2] = z.y;
            mRot.M[2, 2] = z.z;
            mRot.M[3, 3] = 1.0f;

            return mRot;
        }

    }
}
